home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
dtype
/
mcsnd107.lha
/
Source
/
ScanResourceFile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-03
|
8KB
|
306 lines
/*
** MacSND DataType
**
** Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
** Public domain
**
** :ts=4
*/
#include "Global.h"
// We want to use the locals
#undef SysBase
#define SysBase SysBase
#undef DOSBase
#define DOSBase DOSBase
// initCmd opcode controls
#define initMono 0x80 // A monophonic channel, please
#define initStereo 0xC0 // Two stereo channels, please
// Opcodes to replay sound
#define soundCmd 0x50 // Play a sound or a note
#define bufferCmd 0x51 // Play a sound
// Offset indicator
#define dataOffsetFlag 0x8000 // Data follows
/* ReadMacBinaryHeader():
*
* Read the MacBinary format header and seek to the
* proper resource location
*/
BOOL __regargs
ReadMacBinaryHeader(BPTR Handle,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
{
MacBinaryHeader Header;
// No error so far
*Error = 0;
// Read the header, this should be 128 bytes
if(FRead(Handle,&Header,sizeof(MacBinaryHeader),1) == 1)
{
LONG Offset;
// The data is found at an odd address...
CopyMem(Header . dflen,&Offset,sizeof(Offset));
// Pad the offset to a multiple of 128, I suppose
// this is done in order to keep XModem happy
Offset = 128 + ((Offset + 127) & ~127);
// Seek to the resource data location
if(Seek(Handle,Offset,OFFSET_BEGINNING) != -1)
return(TRUE);
else
*Error = ERROR_SEEK_ERROR;
}
// No success
return(FALSE);
}
/* ReadSoundHeader():
*
* Fill in the BufferCmd data structure
*/
BOOL __regargs
ReadSoundHeader(BPTR Handle,LONG SoundResourceOffset,struct SoundDataHeader *SoundHeader,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
{
WORD HeaderWords[2],NumCommands,i;
// Read the two header words
if(FRead(Handle,&HeaderWords,sizeof(HeaderWords),1) == 1)
{
// Is this a type 1 "snd " resource?
if(HeaderWords[0] == 1)
{
// How many synthesizer entries are there?
if(HeaderWords[1])
{
struct SynthHeader { WORD ID; LONG Init; } SynthHeader;
// Check all synthesizer init opcodes
for(i = 0 ; !(*Error) && i < HeaderWords[1] ; i++)
{
// Read the init header
if(FRead(Handle,&SynthHeader,sizeof(SynthHeader),1) == 1)
{
// Stereo sounds are not supported
if((SynthHeader . Init & 0xF0) == initStereo)
return(FALSE);
}
}
}
}
else
{
// Only type 1 and type 2 resources are supported
if(HeaderWords[0] < 1 || HeaderWords[0] > 2)
return(FALSE);
}
// Read the number of commands to follow
if(FRead(Handle,&NumCommands,sizeof(NumCommands),1) == 1)
{
// Are there any commands following?
if(NumCommands)
{
struct SoundCommand { UWORD Command; WORD Param1; LONG Param2; } SoundCommand;
// Scan through the commands
for(i = 0 ; !(*Error) && i < NumCommands ; i++)
{
// Read the next command
if(FRead(Handle,&SoundCommand,sizeof(SoundCommand),1) == 1)
{
// Is this a soundCmd or bufferCmd and does it
// have data following it?
if(SoundCommand . Command == (dataOffsetFlag | soundCmd) || SoundCommand . Command == (dataOffsetFlag | bufferCmd))
{
// Seek to the bufferCmd header
if(Seek(Handle,SoundResourceOffset + SoundCommand . Param2,OFFSET_BEGINNING) != -1)
{
// Read the sound header
if(FRead(Handle,SoundHeader,sizeof(struct SoundDataHeader),1) == 1)
{
// Compressed sounds are not supported
if(SoundHeader -> Encoding == stdSH)
{
// Seek to the location of the data
if(Seek(Handle,SoundHeader -> DataOffset & 0x00FFFFFF,OFFSET_CURRENT) != -1)
return(TRUE);
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
}
}
else
*Error = IoErr();
}
else
*Error = IoErr();
return(FALSE);
}
/* ScanResource():
*
* Scan a resource file for "snd " resources.
*/
BOOL __regargs
ScanResource(BPTR Handle,struct SoundDataHeader *SoundHeader,LONG *Error,struct ExecBase *SysBase,struct DosLibrary *DOSBase)
{
struct ResourceHeader ResourceHeader;
struct ResourceMapHeader ResourceMapHeader;
struct ResourceTypeHeader ResourceTypeHeader;
struct ResourceTypeEntry ResourceTypeEntry;
struct ResourceReference ResourceReference;
LONG Origin = Seek(Handle,0,OFFSET_CURRENT),i,j;
// No error so far
*Error = 0;
// Read the resource header
if(FRead(Handle,&ResourceHeader,sizeof(ResourceHeader),1) == 1)
{
// Seek to the resource map
if(Seek(Handle,ResourceHeader . ResourceMapOffset + Origin,OFFSET_BEGINNING) != -1)
{
// Read the resource map header
if(FRead(Handle,&ResourceMapHeader,sizeof(ResourceMapHeader),1) == 1)
{
// Both the first entries of the resource header and the
// resource map header must match
if(!memcmp(&ResourceHeader,&ResourceMapHeader,4 * sizeof(LONG)))
{
// Seek to the resource type list
if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset,OFFSET_BEGINNING) != -1)
{
// Read the resource type list header
if(FRead(Handle,&ResourceTypeHeader,sizeof(ResourceTypeHeader),1) == 1)
{
// Examine all entries
for(i = 0 ; !(*Error) && i <= ResourceTypeHeader . ResourceEntryCount ; i++)
{
// Seek to an entry
if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset + sizeof(struct ResourceTypeHeader) + i * sizeof(struct ResourceTypeEntry),OFFSET_BEGINNING) != -1)
{
// Read a resource type list entry
if(FRead(Handle,&ResourceTypeEntry,sizeof(ResourceTypeEntry),1) == 1)
{
// Examine all resources of this type
for(j = 0 ; !(*Error) && j <= ResourceTypeEntry . ResourceCount ; j++)
{
// Seek to the resource reference
if(Seek(Handle,Origin + ResourceHeader . ResourceMapOffset + ResourceMapHeader . ResourceTypeListOffset + ResourceTypeEntry . ResourceReferenceOffset + j * sizeof(struct ResourceReference),OFFSET_BEGINNING) != -1)
{
// Read the resource reference header
if(FRead(Handle,&ResourceReference,sizeof(ResourceReference),1) == 1)
{
// Is this a "snd " type resource?
if(!memcmp(ResourceTypeEntry . ResourceType,"snd ",4))
{
// Seek to the corresponding resource data entry
if(Seek(Handle,Origin + ResourceMapHeader . ResourceDataOffset + (ResourceReference . ResourceInfo & 0xFFFFFF) + sizeof(LONG),OFFSET_BEGINNING) != -1)
{
// Process the sound header
if(ReadSoundHeader(Handle,Origin + ResourceMapHeader . ResourceDataOffset + (ResourceReference . ResourceInfo & 0x00FFFFFF) + sizeof(LONG),SoundHeader,Error,SysBase,DOSBase))
return(TRUE);
}
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
else
*Error = ERROR_SEEK_ERROR;
}
}
else
*Error = IoErr();
}
else
*Error = ERROR_SEEK_ERROR;
}
else
*Error = IoErr();
return(FALSE);
}